import random
import string
from abc import ABC, abstractmethod
from typing import List

from po import UserEntity
from vo import UserInfo
from db_config import Session


def generate_universe_id(length=11):
    chars = string.ascii_letters + string.digits
    random_id = ''.join(random.choice(chars) for _ in range(length))
    return random_id


class UserService(ABC):

    @abstractmethod
    def user_register(self, username: str, password: str) -> UserInfo | None:
        pass

    @abstractmethod
    def user_login(self, username: str, password: str) -> UserInfo | None:
        pass

    @abstractmethod
    def get_user_info(self, user_id: str) -> UserInfo | None:
        pass


class UserServiceImpl(UserService):

    def user_register(self, username, password) -> UserInfo | None:
        with Session() as session:
            selected_user_entity: UserEntity = session.query(UserEntity).filter_by(user_name=username).first()
            if selected_user_entity is not None:
                return None

            new_user_entity: UserEntity = UserEntity(
                user_id=generate_universe_id(),
                user_name=username,
                user_password=password,
                user_role='user'
            )
            session.add(new_user_entity)
            session.commit()
            new_user_entity: UserEntity = session.query(UserEntity).filter_by(user_id=new_user_entity.user_id).first()
            user: UserInfo = UserInfo(**new_user_entity.__dict__)
            return user


    def user_login(self, username, password) -> UserInfo | None:
        with Session() as session:
            selected_user_entity: UserEntity = session.query(UserEntity).filter_by(user_name=username).first()
            if selected_user_entity is None:
                return None
            if selected_user_entity.user_password == password:
                user: UserInfo = UserInfo(**selected_user_entity.__dict__)
                return user
            else:
                return None


    def get_user_info(self, user_id: str) -> UserInfo | None:
        with Session() as session:
            selected_user_entity: UserEntity = session.query(UserEntity).filter_by(user_id=user_id).first()
            if selected_user_entity is None:
                return None
            else:
                user: UserInfo = UserInfo(**selected_user_entity.__dict__)
                return user